package com.thememaker.lockstyle.control;

import com.alibaba.fastjson.JSON;
import com.thememake.ui.Toast;
import com.thememaker.lockstyle.AnimationUtils;
import com.thememaker.lockstyle.LockStyleCenterEditUtils;
import com.thememaker.lockstyle.LockStyleCenterLeftEditUtils;
import com.thememaker.lockstyle.LockstyleShowUtils;
import com.thememaker.lockstyle.bean.Var;
import com.thememaker.lockstyle.bean.command.*;
import com.thememaker.lockstyle.bean.ui.BaseView;
import com.thememaker.lockstyle.bean.ui.Image;
import com.thememaker.lockstyle.parsii.ExpressionUtils;
import javafx.animation.ParallelTransition;
import javafx.animation.Timeline;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @author yiyi.zheng 2018/9/18
 */
public class LockstyleShowRightEventControl {
    private float rate = 480f / 1080f;
    private ExpressionUtils expressionUtils;
    private Stage stage;
    private LockstyleShowUtils lockstyleShowUtils;
    private LockStyleCenterEditUtils lockStyleCenterEditUtils;
    private LockStyleCenterLeftEditUtils lockStyleCenterLeftEditUtils;
    private Path lockscreenPath;
    private boolean isDoubleClick = false;
    private LinkedHashMap<String, BaseView> groupMap;

    private List<Button> selectButton;
    private List<BaseView> selectBaseView;
    private boolean isMove = false;
    private double clickX, clickY;

    //垂直移动与水平移动
    private boolean xxxxx = false;
    private boolean yyyyy = false;

    public LockstyleShowRightEventControl(ExpressionUtils expressionUtils, Stage stage, LockstyleShowUtils lockstyleShowUtils,
                                          LockStyleCenterEditUtils lockStyleCenterEditUtils, LockStyleCenterLeftEditUtils lockStyleCenterLeftEditUtils,
                                          Path lockscreenPath) {
        this.expressionUtils = expressionUtils;
        this.stage = stage;
        this.lockstyleShowUtils = lockstyleShowUtils;
        this.lockStyleCenterEditUtils = lockStyleCenterEditUtils;
        this.lockStyleCenterLeftEditUtils = lockStyleCenterLeftEditUtils;
        this.lockscreenPath = lockscreenPath;

        selectButton = new ArrayList<>();
        selectBaseView = new ArrayList<>();
    }

    //编辑状态下拖动事件响应
    public void initButtonEvent(BaseView baseView, Button button, String baseStyle) {
        System.err.println("initButtonEvent >>> " + JSON.toJSONString(baseView));
        //鼠标进入区域
        button.addEventHandler(MouseEvent.MOUSE_ENTERED, event -> {
            if (selectButton.indexOf(button) >= 0) {
                button.setStyle("-fx-border-color: rgb(76,140,245);-fx-background-color: rgb(76,140,245,0.5);");
                button.setStyle(button.getStyle() + baseStyle);
            } else {
                button.setStyle("-fx-border-color: rgb(76,140,245);-fx-background-color: rgb(76,140,245,0.3);");
                button.setStyle(button.getStyle() + baseStyle);
            }
        });
        //鼠标离开区域
        button.addEventHandler(MouseEvent.MOUSE_EXITED, event -> {
            System.err.println("vBox >>> MOUSE_EXITED");
            if (selectButton.indexOf(button) >= 0) {
                button.setStyle("-fx-border-color: rgb(76,140,245);-fx-background-color: rgb(76,140,245,0.5);");
                button.setStyle(button.getStyle() + baseStyle);
            } else {
                button.setStyle("-fx-border-color: transparent;-fx-background-color: transparent;");
                button.setStyle(button.getStyle() + baseStyle);
            }
        });
        //鼠标释放区域
        button.addEventHandler(MouseEvent.MOUSE_RELEASED, event -> {
            System.err.println("vBox >>> MOUSE_RELEASED");
            addButtonKeyBoardEvent(button);
            if (selectButton.indexOf(button) >= 0) {
                if (!isMove) {
                    selectButton.remove(button);
                    selectBaseView.remove(baseView);
                    button.setStyle(button.getStyle() + "-fx-border-color: rgb(76,140,245);-fx-background-color: rgb(76,140,245,0.3);");
                    button.setStyle(button.getStyle() + baseStyle);
                }
            } else {
                selectButton.add(button);
                selectBaseView.add(baseView);
                button.setStyle("-fx-border-color: rgb(76,140,245);-fx-background-color: rgb(76,140,245,0.5);");
                button.setStyle(button.getStyle() + baseStyle);
            }
        });
        //鼠标点击区域
        button.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
            isMove = false;
            clickX = event.getX();
            clickY = event.getY();
            System.err.println("vBox >>> MOUSE_PRESSED " + clickX);
            button.setStyle("-fx-border-color: rgb(76,140,245);-fx-background-color: rgb(76,140,245,0.5);");
            button.setStyle(button.getStyle() + baseStyle);
            if (LayoutComponentUtils.patternID == 2 && lockStyleCenterEditUtils != null) {
                lockStyleCenterLeftEditUtils.updateCenterTextInfo(baseView, expressionUtils, lockstyleShowUtils);
                lockStyleCenterEditUtils.updateRightImageInfo(baseView, lockscreenPath, lockstyleShowUtils);
            }
        });
        //鼠标点击移动区域
        button.addEventHandler(MouseEvent.MOUSE_DRAGGED, event -> {
            isMove = true;
            System.err.println("vBox >>> MOUSE_DRAGGED ");
            double x = event.getX();
            double y = event.getY();
            double moveX = x - clickX;
            double moveY = y - clickY;
            if (selectButton.indexOf(button) >= 0) {
                for (int i = 0; i < selectButton.size(); i++) {
                    button.setOnKeyPressed(broadKey -> {
                        if (broadKey.getCode() == KeyCode.SHIFT) {
                            xxxxx = true;
                        } else if (broadKey.getCode() == KeyCode.CONTROL) {
                            yyyyy = true;
                        }
                    });
                    button.setOnKeyReleased(broadKey -> {
                        if (broadKey.getCode() == KeyCode.SHIFT) {
                            xxxxx = false;
                        } else if (broadKey.getCode() == KeyCode.CONTROL) {
                            yyyyy = false;
                        }
                    });
                    if (xxxxx && !yyyyy) {
                        selectButton.get(i).setLayoutX(selectButton.get(i).getLayoutX() + (x - clickX));
                    } else if (xxxxx && yyyyy) {
                        selectButton.get(i).setLayoutY(selectButton.get(i).getLayoutY() + (y - clickY));
                    } else {
                        selectButton.get(i).setLayoutX(selectButton.get(i).getLayoutX() + (x - clickX));
                        selectButton.get(i).setLayoutY(selectButton.get(i).getLayoutY() + (y - clickY));
                    }
                    int saveX = (int) (selectButton.get(i).getLayoutX() + moveX);
                    int saveY = (int) (selectButton.get(i).getLayoutY() + moveY);

                    selectBaseView.get(i).setX(splitXYValue(selectBaseView.get(i).getX()) + (int) (saveX / rate));
                    selectBaseView.get(i).setY(splitXYValue(selectBaseView.get(i).getY()) + (int) (saveY / rate));

                }
            }
        });
        addButtonKeyBoardEvent(button);
    }

    private void addButtonKeyBoardEvent(Button button) {
        button.setOnKeyReleased(event -> {
            System.err.println("vBox >>> KEYBOARD_EVENT ");
            for (int i = 0; i < selectButton.size(); i++) {
                double saveX = selectButton.get(i).getLayoutX();
                double saveY = selectButton.get(i).getLayoutY();
                switch (event.getCode()) {
                    case LEFT:
                        selectButton.get(i).setLayoutX(selectButton.get(i).getLayoutX() - 1);
                        saveX = selectButton.get(i).getLayoutX() - 1;
                        break;
                    case UP:
                        selectButton.get(i).setLayoutY(selectButton.get(i).getLayoutY() - 1);
                        saveY = selectButton.get(i).getLayoutY() - 1;
                        break;
                    case RIGHT:
                        selectButton.get(i).setLayoutX(selectButton.get(i).getLayoutX() + 1);
                        saveX = selectButton.get(i).getLayoutX() + 1;
                        break;
                    case DOWN:
                        selectButton.get(i).setLayoutY(selectButton.get(i).getLayoutY() + 1);
                        saveY = selectButton.get(i).getLayoutY() + 1;
                        break;
                    default:
                        break;
                }
                selectBaseView.get(i).setX(splitXYValue(selectBaseView.get(i).getX()) + (int) (saveX / rate));
                selectBaseView.get(i).setY(splitXYValue(selectBaseView.get(i).getY()) + (int) (saveY / rate));
            }
        });
    }

    //非编辑状态下按钮的点击事件响应
    public void initButtonClickEvent(BaseView baseView, Button button, LinkedHashMap<String, BaseView> groupMap, Consumer<LinkedHashMap<String, BaseView>> consumer) {
        this.groupMap = groupMap;
        //鼠标进入区域
        button.addEventHandler(MouseEvent.MOUSE_ENTERED, event -> {
            button.setStyle("-fx-border-color: rgb(76,140,245);-fx-background-color: rgb(76,140,245,0.3);");
        });
        //鼠标离开区域
        button.addEventHandler(MouseEvent.MOUSE_EXITED, event -> {
            button.setStyle("-fx-border-color: transparent;-fx-background-color: transparent;");
        });
        //鼠标释放区域
        button.addEventHandler(MouseEvent.MOUSE_RELEASED, event -> {
            button.setStyle("-fx-border-color: rgb(76,140,245);-fx-background-color: rgb(76,140,245,0.3);");
            buttonClickUpAndDouble(baseView, consumer);
        });
        //鼠标点击区域
        button.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
            button.setStyle("-fx-border-color: rgb(76,140,245);-fx-background-color: rgb(76,140,245,0.5);");
            buttonClickDown(baseView, consumer);
        });
    }

    private void buttonClickUpAndDouble(BaseView baseView, Consumer<LinkedHashMap<String, BaseView>> consumer) {
        if (baseView instanceof com.thememaker.lockstyle.bean.ui.Button) {
            com.thememaker.lockstyle.bean.ui.Button btnBV = (com.thememaker.lockstyle.bean.ui.Button) baseView;
            if (btnBV.getTriggers() != null && btnBV.getTriggers().getTriggerMap() != null && !btnBV.getTriggers().getTriggerMap().isEmpty()) {
                btnBV.getTriggers().getTriggerMap().keySet().forEach(key -> {
                    Trigger trigger = btnBV.getTriggers().getTriggerMap().get(key);
                    if (trigger.getAction().equals("up")) {
                        clickBtnCommand(trigger, "up", consumer);
                    } else if (trigger.getAction().equals("double")) {
                        if (isDoubleClick) {
                            clickBtnCommand(trigger, "double", consumer);
                        } else {
                            isDoubleClick = true;
                            new Thread(() -> {
                                try {
                                    Thread.sleep(200);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                } finally {
                                    isDoubleClick = false;
                                }
                            }).start();
                        }
                    }
                });
            }
        }
    }

    private void buttonClickDown(BaseView baseView, Consumer consumer) {
        if (baseView instanceof com.thememaker.lockstyle.bean.ui.Button) {
            com.thememaker.lockstyle.bean.ui.Button btnBV = (com.thememaker.lockstyle.bean.ui.Button) baseView;
            if (btnBV.getTriggers() != null && btnBV.getTriggers().getTriggerMap() != null && !btnBV.getTriggers().getTriggerMap().isEmpty()) {
                btnBV.getTriggers().getTriggerMap().keySet().forEach(key -> {
                    Trigger trigger = btnBV.getTriggers().getTriggerMap().get(key);
                    if (trigger.getAction().equals("down")) {
                        clickBtnCommand(trigger, "down", consumer);
                    }
                });
            }
        }
    }

    private void clickBtnCommand(Trigger trigger, String mouseType, Consumer<LinkedHashMap<String, BaseView>> consumer) {
        if (trigger.getCommandMap() != null && !trigger.getCommandMap().isEmpty()) {
            trigger.getCommandMap().keySet().forEach(commandKey -> {
                BaseCommand baseCommand = trigger.getCommandMap().get(commandKey);
                if (baseCommand instanceof VariableCommand) {
                    VariableCommand variableCommand = (VariableCommand) baseCommand;
                    expressionUtils.addVariable(variableCommand.getName(), expressionUtils.parseExpr(variableCommand.getExpression()));
                    for (String key : groupMap.keySet()) {
                        if (groupMap.get(key) instanceof Var) {
                            Var var = (Var) groupMap.get(key);
                            if (var.getName().equals(variableCommand.getName())) {
                                var.setExpression(((int) expressionUtils.parseExpr(variableCommand.getExpression())) + "");
                            }
                        }
                    }
                } else if (baseCommand instanceof Command) {
                    System.out.println("Command >>> 动画控制");
                } else if (baseCommand instanceof SoundCommand) {
                    System.out.println("Command >>> 声音控制");
                } else if (baseCommand instanceof VibratorCommand) {
                    System.out.println("Command >>> 震动控制");
                } else if (baseCommand instanceof IntentCommand) {
                    IntentCommand intentCommand = (IntentCommand) baseCommand;
                    Toast.makeText(stage, "打开快捷 >>> " + intentCommand.getClassString(), 2000);
                    System.out.println("Command >>> 打开快捷 >>> " + intentCommand.getClassString());
                } else if (baseCommand instanceof ExternCommand){
                    Toast.makeText(stage, "解锁", 2000);
                    System.out.println("Command >>> 解锁");
                }
            });
            consumer.accept(groupMap);
            lockstyleShowUtils.updateRightPreview();
        }
    }

    public void initAnimation(Image image, ImageView imageView, Consumer<ParallelTransition> consumer) {
        ParallelTransition parallelTransition = new ParallelTransition();
        if (image.getPositionAnimation() != null && image.getPositionAnimation().getPositionList() != null) {
            parallelTransition.getChildren().add(AnimationUtils.initPositionAnimation(imageView, image.getPositionAnimation().getPositionList(), rate));
        }
        if (image.getSourcesAnimation() != null && image.getSourcesAnimation().getSourceList() != null) {
            parallelTransition.getChildren().add(AnimationUtils.initSourceAnimation(imageView, lockscreenPath.toString(), image.getSourcesAnimation().getSourceList(), rate));
        }
        if (image.getSizeAnimation() != null && image.getSizeAnimation().getSizeList() != null) {
            parallelTransition.getChildren().add(AnimationUtils.initSizeAnimation(imageView, image.getSizeAnimation().getSizeList(), rate));
        }
        if (image.getRotationAnimation() != null && image.getRotationAnimation().getRotationList() != null) {
            parallelTransition.getChildren().add(AnimationUtils.initRotationAnimation(imageView, image.getRotationAnimation().getRotationList(), rate));
        }
        if (image.getAlphaAnimation() != null && image.getAlphaAnimation().getAlphaList() != null) {
            parallelTransition.getChildren().add(AnimationUtils.initAlphaAnimation(imageView, image.getAlphaAnimation().getAlphaList(), rate));
        }
        consumer.accept(parallelTransition);

        parallelTransition.setCycleCount(Timeline.INDEFINITE);
        parallelTransition.play();
    }


    public static String splitXYValue(String value) {
        String[] strArr = value.split("[+-]");
        StringBuffer sbVar = new StringBuffer();
        for (String str : strArr) {
            if (str.contains("screen_height")) {
                sbVar.append(str).append("-1920").append("+");
            } else if (str.contains("#")) {
                sbVar.append(str).append("+");
            }
        }
        return sbVar.toString();
    }
}
